package com.liang.controller;


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.JOptionPane;

import org.apache.commons.io.IOUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.liang.exception.CaptchaEmptyException;
import com.liang.exception.CaptchaErrorException;
import com.liang.pojo.User;
import com.liang.service.UserService;
import com.liang.shiro.CaptchaToken;

@Controller
public class UserController {

	@Autowired
	UserService userService;

	@RequestMapping("/toLogin")
	public String toLogin(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException {
		Integer count = (Integer) request.getServletContext().getAttribute("count");
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		if(count==null) {
			request.getServletContext().setAttribute("count", 1);
		}else {
			request.getServletContext().setAttribute("count", count++);
		}
		//以上是统计网页访问量，没啥用，可以获取对方地址主机等信息，就是没啥用
		return "login";
	}
	@RequestMapping("/toMain")
	public String toMain() throws IOException {
		InputStream inputStream=this.getClass().getClassLoader().getResourceAsStream("log4j.properties");//resources路径
		InputStream inputStream2 = this.getClass().getResourceAsStream("");//com/liang/controller路径
		OutputStream outputStream=new FileOutputStream("D:\\wenjian");
		byte[] b=new byte[1024];//自定义缓冲区
		int len=0;
		if((len=inputStream.read(b))!=-1){
			outputStream.write(b,0,len);
		}
		outputStream.close();
		inputStream.close();
		//上面是不建议的io流操作，下面是高效的，其实也差不多吧，少了个自定义缓冲区，但是多了一行代码,以后用IOUtils来操作
		BufferedInputStream bi=new BufferedInputStream(inputStream);
		BufferedOutputStream bo = new BufferedOutputStream(outputStream);
		if((len=bi.read())!=-1) {
			bo.write(len);
		}
		bo.close();
		bi.close();
		return "main";
	}
	@RequestMapping("/user/toInsert")
	public String toInsert() {
		return "insert";
	}
	
	@RequestMapping("/user/login")
	public String login(@RequestParam("username")String u,@RequestParam("password")String p,
			@RequestParam("captchacode")String captchacode,@RequestParam(value = "checkbox",defaultValue = "0")int checkbox,Model model,
			HttpServletRequest request) {
		Subject currentUser = SecurityUtils.getSubject();
		if(!currentUser.isAuthenticated()) {
			CaptchaToken token=new CaptchaToken(u,p,captchacode);
			System.out.println("+++++++++++++++++++++++++++"+checkbox);
			model.addAttribute("username",u);
			if(checkbox==1) {
				token.setRememberMe(true);
			}
			try {
				currentUser.login(token);
				request.getSession().setAttribute("username", u);
			} catch (UnknownAccountException uae) {
				model.addAttribute("msg", "用户名不存在");
				return "login";
			} catch (IncorrectCredentialsException ice) {
				model.addAttribute("msg2", "密码错误");
				return "login";
			} catch (CaptchaEmptyException cee) {
				model.addAttribute("msg3", "验证码为空");
				return "login";
			} catch (CaptchaErrorException CEE) {
				model.addAttribute("msg3", "验证码错误");
				return "login";
			} catch (LockedAccountException lae) {
				model.addAttribute("msg", "拒绝访问");
				return "login";
			} catch (AuthenticationException ae) {
				model.addAttribute("msg", "未知错误");
				return "login";
			}
		}
		return "redirect:/toMain";
//		return "main";
	}
	
	@ResponseBody
	@RequestMapping("/user/selectByUsername")
	public int selectByUsername(@RequestParam("username")String username) {
		String uPattern ="/^[a-zA-Z0-9_-]{4,16}$/";
		String uPattern2 ="//^[a-zA-Z0-9_-]{4,16}$//";
		String uPattern3 ="^[a-zA-Z0-9_-]{4,16}$";
		String uPattern4 ="[a-zA-Z0-9_-]{4,16}";
		System.out.println(username.matches(uPattern)+"+");
		System.out.println(username.matches(uPattern2)+"++");
		System.out.println(username.matches(uPattern3)+"+++");
		System.out.println(username.matches(uPattern4)+"++++");
		if(username.matches(uPattern3)){
			Map<String,Object> map=new TreeMap<String,Object>();
			map.put("username", username);
			User user = userService.selectUserByUsername(map);
			if(user!=null) {
				return 1;
			}
			return 0;
		}
		return -1;
	}
	
	@RequestMapping("/user/insert")
	public String insert(User user,Model model) {
		String password=user.getPassword();
		String pPattern="^[a-zA-Z0-9]{4,10}$"; 
		System.out.println(password.matches(pPattern)+"+++++");
		if(password.matches(pPattern)) {
			int i = selectByUsername(user.getUsername());
			if(i==1) {
				model.addAttribute("uInfo", "注册失败，用户名已存在(后端)");
				return "insert";
			}
			if(i==-1) {
				model.addAttribute("uInfo", "注册失败，用户名不符合规范(后端)");
				return "insert";
			}
			user.setSalt("狂神");
			Object md5 =MD5(user);
			user.setPassword(md5.toString());
			userService.insertUser(user);
			model.addAttribute("info", "注册成功，打个勾");
			return "login";
		}else {
			model.addAttribute("pInfo", "注册失败，密码不符合规范(后端)");
			return "insert";
		}
	}
	
	public Object MD5(User user) {
		//	  若要使用MD5加密，数据库中的密码也得是加密后的密码可以通过下面的方法获取明文密码对应的密文密码 
		String hashAlgorithName ="MD5";
		String password = user.getPassword();
		int hashIterations = 527;
		ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
		Object obj = new SimpleHash(hashAlgorithName, password, credentialsSalt,hashIterations);
		System.out.println(obj);
		return obj;
	}
}
